#============================================================
#    Skill Data Monitor
#============================================================
# - datetime: 2022-11-24 22:09:36
#============================================================
##技能数据监听器
##
##以 [DataManagement] 作为存储技能数据的对象
class_name SkillDataMonitor
extends DataManagementMonitor


signal newly_added_skill(skill: Skill, data: Dictionary)
signal removed_skill(skill: Skill, data: Dictionary)


## [Dictionary] 数据中值为 [Skill] 的 key
const SKILL_NODE_KEY = "##node"


#============================================================
#  连接优先级信号
#============================================================
## 连接优先级技能信号
func _connect_priority_skill_signal(signal_name: StringName, callback: Callable, priority: int):
	# 以优先级连接信号
	var skill : Skill
	for data in get_data_management().get_all_data().values():
		skill = get_skill_by_data(data)
		# 连接这个 skill 的队列回调对象
		PriorityCallableConnector.instance(skill).add_callable(signal_name, callback, priority)

## 开始调用了技能
func connect_casted(callback: Callable, priority: int = 10):
	_connect_priority_skill_signal(SkillConstants.Signals.CASTED, callback, priority)

## 执行准备（前摇动作）
func connect_execute_ready(callback: Callable, priority: int = 10):
	_connect_priority_skill_signal(SkillConstants.Signals.EXECUTE_READY, callback, priority)

## 执行前
func connect_execute_before(callback: Callable, priority: int = 10):
	_connect_priority_skill_signal(SkillConstants.Signals.EXECUTE_BEFORE, callback, priority)

## 执行中
func connect_executing(callback: Callable, priority: int = 10):
	_connect_priority_skill_signal(SkillConstants.Signals.EXECUTING, callback, priority)

## 执行后
func connect_execute_after(callback: Callable, priority: int = 10):
	_connect_priority_skill_signal(SkillConstants.Signals.EXECUTE_AFTER, callback, priority)

## 执行完成（后摇动作结束）
func connect_execute_ended(callback: Callable, priority: int = 10):
	_connect_priority_skill_signal(SkillConstants.Signals.EXECUTE_ENDED, callback, priority)

## 状态刷新了（冷却时间结束了）
func connect_refreshed(callback: Callable, priority: int = 10):
	_connect_priority_skill_signal(SkillConstants.Signals.REFRESHED, callback, priority)

## 停止（调用 [method stop] 方法时发出这个信号）
func connect_stopped(callback: Callable, priority: int = 10):
	_connect_priority_skill_signal(SkillConstants.Signals.STOPPED, callback, priority)

## 中断（调用 [method interrupt] 方法中断成功时发出这个信号）
func connect_interrupted(callback: Callable, priority: int = 10):
	_connect_priority_skill_signal(SkillConstants.Signals.INTERRUPTED, callback, priority)


#============================================================
#  SetGet
#============================================================
static func get_skill_by_data(data: Dictionary) -> Skill:
	return data.get(SKILL_NODE_KEY) as Skill


func get_skill(skill_name) -> Skill:
	var data = get_data_management().get_property(skill_name)
	return get_skill_by_data(data)



#============================================================
#  重写
#============================================================
#(override)
func _newly_added_property(property, value: Dictionary):
	print("-- 新增：", property)
	
	# 增加 node 属性数据
	var skill = Skill.new()
	value[SKILL_NODE_KEY] = skill
	add_child(skill)
	newly_added_skill.emit(skill, value)
	
	# 这个信号发出信号的时候会调用这个优先级回调
	for signal_name in SkillConstants.Signals.values():
		skill.connect(signal_name, PriorityCallableConnector.instance(skill).call_callable.bind(signal_name))


#(override)
func _property_changed(property, previous: Dictionary, current: Dictionary):
	current[SKILL_NODE_KEY] = previous[SKILL_NODE_KEY]


#(override)
func _removed_property(property, value: Dictionary):
	var skill = get_skill_by_data(value)
	if skill:
		removed_skill.emit(skill, value)
		skill.queue_free()



#============================================================
#  自定义
#============================================================
##  施放技能
##[br]
##[br][code]skill_name[/code]  技能名称
##[br][code]input_data[/code]  传入技能的数据
func cast_skill(skill_name, input_data: Dictionary = {}):
	var skill = get_skill(skill_name)
	if skill:
		skill.run(input_data)
	else:
		printerr(self, " 没有这个技能。skill_name = ", skill_name)

